package com.huimei.hmc.upms.client.shiro.realm;

import com.huimei.hmc.upms.client.common.constant.UpmsClientConstant;
import com.huimei.hmc.upms.sys.api.IUpmsUserService;
import com.huimei.hmc.upms.sys.pojo.model.UpmsUser;
import com.huimei.hmc.common.util.PropertiesFileUtil;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.crypto.hash.SimpleHash;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.util.ByteSource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.HashSet;
import java.util.Set;

/**
 * Created by Huangyuheng on 2017/7/6.
 */
public class UpmsRealm extends AuthorizingRealm {

    private static final Logger logger = LoggerFactory.getLogger(UpmsRealm.class.getName());

    private String algorithmName = "md5";
    private int hashIterations = 2;

    @Autowired
    private IUpmsUserService upmsUserService;

    /**
     * 授权：验证权限时调用
     *
     * @param principalCollection
     * @return
     */
    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principalCollection) {

        String username = (String) principalCollection.getPrimaryPrincipal();

        Set<String> permissions = upmsUserService.getUpmsUserPermission(username);
        Set<String> roles = upmsUserService.getUpmsUserRoleCode(username);

//        Set<String> permissions = new HashSet<>();
//        permissions.add("sys:user:list");
//        permissions.add("sys:user:add");
//        permissions.add("sys:user:edit");
//        permissions.add("sys:user:delete");
//        permissions.add("sys:user:editVM");

        SimpleAuthorizationInfo simpleAuthorizationInfo = new SimpleAuthorizationInfo();
        simpleAuthorizationInfo.setStringPermissions(permissions);
        simpleAuthorizationInfo.setRoles(roles);

        return simpleAuthorizationInfo;
    }

    /**
     * 认证：登录时调用
     *
     * @param authenticationToken
     * @return
     * @throws AuthenticationException
     */
    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {

        String username = (String) authenticationToken.getPrincipal();
        String password = new String((char[]) authenticationToken.getCredentials());

        // client无密认证
        String upmsType = PropertiesFileUtil.getInstance(UpmsClientConstant.HMC_UPMS_CLIENT).get(UpmsClientConstant.UPMS_TYPE);
        if (UpmsClientConstant.UPMS_TYPE_CLIENT.equals(upmsType)) {
            return new SimpleAuthenticationInfo(username, password, getName());
        }

        UpmsUser upmsUser = upmsUserService.getUpmsUserByUsername(username);

        if (null == upmsUser) {
            throw new UnknownAccountException("帐号或密码错误不存在！");
        }

        String newPassword = new SimpleHash(
                algorithmName,
                password,
                ByteSource.Util.bytes(upmsUser.getSalt()),
                hashIterations).toHex();

        if (!upmsUser.getPassword().equals(newPassword)) {
            throw new IncorrectCredentialsException("帐号或密码错误不存在！");
        }

        if (upmsUser.getLocked() == 1) {
            throw new LockedAccountException("帐号已锁定！");
        }

        return new SimpleAuthenticationInfo(username, password, getName());
    }

}
